package com.kaoshi.myweb.common.seachable;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.kaoshi.myweb.common.seachable.Criteria.Criterion;

/**
 * 查询条件
 * 
 * @author tangx
 * @since 2014年10月29日
 */

public class QueryCondition extends Condition {
	protected Set<String> groupByColumns;
	
	protected OrderCriteria orderCriteria;

	public OrderCriteria getOrderCriteria() {
		return orderCriteria;
	}

	protected boolean distinct;

	public QueryCondition() {
		super();
		groupByColumns = new HashSet<String>();
		orderCriteria = new OrderCriteria();
	}

	@Override
	public QueryCondition or(Criteria criteria) {
		criterias.add(criteria);
		return (QueryCondition) this;
	}

	public QueryCondition desc(String column) {
		orderCriteria.addDescFields(column);
		return (QueryCondition) this;
	}

	public QueryCondition asc(String column) {
		orderCriteria.addAscFields(column);
		return (QueryCondition) this;
	}

	public QueryCondition groupBy(String column) {
		groupByColumns.add(column);
		return (QueryCondition) this;
	}

	public QueryCondition desc(String[] columns) {
		for (String string : columns) {
			orderCriteria.addDescFields(string);
		}
		return (QueryCondition) this;
	}

	public QueryCondition asc(String[] columns) {
		for (String string : columns) {
			orderCriteria.addAscFields(string);
		}
		
		return (QueryCondition) this;
	}

	public QueryCondition groupBy(String[] columns) {
		groupByColumns.addAll(Arrays.asList(columns));
		return (QueryCondition) this;
	}

	public Set<String> getGroupByColumns() {
		return groupByColumns;
	}

	public boolean isDistinct() {
		return distinct;
	}

	public QueryCondition setDistinct(boolean distinct) {
		this.distinct = distinct;
		return (QueryCondition) this;
	}

	@Override
	public void clear() {
		super.clear();
		orderCriteria.orderCriterions.clear();
		groupByColumns.clear();
		distinct = false;
	}

	@Override
	public QueryCondition transform(Class<?> clazz) {
		super.transform(clazz);
		groupByColumns = transformSet(clazz, groupByColumns);
		return this;
	}
	
	private Set<String> transformSet(Class<?> clazz, Set<String> oldSet){
		Set<String> newSet = new HashSet<String>();
		for (String column : oldSet) {
			newSet.add(getRealColumnName(clazz, column));
		}
		return newSet;
	}
	
	
	public String toSQLString() {
		return where(this);
	}
	
	private String where(Condition query) {
		SQL sql = new SQL();
		List<Criteria> criterias = query.getCriterias();
		int size = criterias.size();
		int i = 0, j = 0;
		for (Criteria criteria : criterias) {
			j = 0;
			for (Criterion criterion : criteria.getCriterions()) {
				String condition = criterion.getCondition();
				Object value = criterion.getValue();
				Object secondValue = criterion.getSecondValue();
				StringBuffer sb = new StringBuffer();
				if (criterion.isNoValue()) {
					sql.SETWHERE(condition);
				} else if (criterion.isSingleValue() && value != null) {
					sql.SETWHERE(condition + value);
				} else if (criterion.isBetweenValue() && value != null
						&& secondValue != null) {
					sql.SETWHERE(condition + value + " AND " + secondValue);
				} else if (criterion.isListValue() && value != null) {
					List<?> valueList = (List<?>) criterion.getValue();
					if (valueList.size() > 0) {
						sb.append("(");
						for (int x = 0; x < valueList.size(); x++) {
							sb.append(value);
							if (x != valueList.size() - 1) {
								sb.append(",");
							}
						}
						sb.append(")");
					}
					sql.SETWHERE(condition + sb.toString());
				}
				j++;
			}
			if (--size > 0) {
				sql.OR();
			}
			i++;
		}
		if (query instanceof QueryCondition) {
//			QueryCondition queryCondition = (QueryCondition) query;
//			Set<String> groupBys = queryCondition.getGroupByColumns();
//			for (String column : groupBys) {
//				if (StringUtils.isNotBlank(column)) {
//					sql.GROUP_BY(column);
//				}
//			}
//			Set<String> ascs = queryCondition.getAscColumns();
//			for (String column : ascs) {
//				if (StringUtils.isNotBlank(column)) {
//					sql.ORDER_BY(column + " asc");
//				}
//			}
//			Set<String> descs = queryCondition.getDescColumns();
//			for (String column : descs) {
//				if (StringUtils.isNotBlank(column)) {
//					sql.ORDER_BY(column + " desc");
//				}
//			}
		}
		return sql.toString();
	}
}
